package com.initialize.core.security.config;

import com.initialize.commom.config.security.SecurityRequestConfig;
import com.initialize.core.security.filter.BaseJwtAuthenticationTokenFilter;
import com.initialize.core.security.handler.*;
import com.initialize.core.security.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.List;
import java.util.Map;


/**
 * Created with IntelliJ IDEA.
 * User: jane
 * Date: 2020/1/2
 * Time: 7:55 下午
 * Description: WebSecurity核心配置
 * The following English comments (including this sentence are translated using plugins, so ...)
 * You can use the translation plugin that comes with idea .....
 */
@Slf4j
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    /**
     * initialize the secure request collection
     */
    protected List<String> securityRequestList = new SecurityRequestConfig().securityRequestList;

    /**
     * Initialize the default permission request collection
     */
    protected Map<String, String> competenceRequestList = new SecurityRequestConfig().competenceRequestList;


//    public SecurityConfiguration(List<String> securityRequestList, Map<String, String> competenceRequestList) {
//        this.securityRequestList = securityRequestList;
//        this.competenceRequestList = competenceRequestList;
//    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .headers()
                .frameOptions().disable();
        http
                .exceptionHandling().accessDeniedHandler(this.baseRestAccessDeniedHandler)
                .authenticationEntryPoint(this.baseAuthenticationEntryPoint);

        http.addFilterBefore(new BaseJwtAuthenticationTokenFilter(userService), UsernamePasswordAuthenticationFilter.class);

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http
                .authorizeRequests();

        for (String o : this.securityRequestList) {
            log.info("o->>  {}", o);
            expressionInterceptUrlRegistry.antMatchers(o).permitAll();
        }

        this.competenceRequestList.forEach((s, s2) -> {
            log.info(s + "--" + s2);
            expressionInterceptUrlRegistry.antMatchers(s).hasRole(s2);
        });

        expressionInterceptUrlRegistry.anyRequest().authenticated()
                .and().formLogin().loginProcessingUrl("/login")
                .successHandler(this.baseAuthenticationSuccessHandler)
                .failureHandler(this.baseAuthenticationFailHandler)
                .permitAll()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().logout().logoutSuccessHandler((request, response, authentication) -> response.getWriter().println("成功退出")).permitAll()
                .and().csrf().disable();

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userService).passwordEncoder(new BCryptPasswordEncoder());
    }


    @Autowired
    UserService userService;

    @Autowired
    BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;

    @Autowired
    BaseAuthenticationFailHandler baseAuthenticationFailHandler;

//    final
//    BaseJwtAuthenticationTokenFilter baseJwtAuthenticationTokenFilter;

    @Autowired
    BaseAuthenticationSuccessHandler baseAuthenticationSuccessHandler;

    @Autowired
    BaseRestAccessDeniedHandler baseRestAccessDeniedHandler;

    @Autowired
    BaseLogoutSuccessHandler baseLogoutSuccessHandler;


}
